﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Web.UI;
using System.Drawing.Design;
using System.Web.UI.HtmlControls;
using System.Diagnostics;
using System.Reflection;

namespace Beetle.Web.UI.WebControls
{
    public abstract class SearchItemBase : IValidator
    {
        internal SearchView Owner { get; set; }
        public const string FieldsSelectExtName = "_ddlFields";
        public const string OperationsSelectExtName = "_ddlOperations";
        public const string ConnectionsSelectExtName = "_ddlConnections";
        public const string ValuesExtName = "_txtValues";
        public const string ItemInfosExtName = "_hidInfos";

        private bool isRenderValueFieldId = false;
        public string FieldName { get; set; }

        public string Text { get; set; }

        public bool IsNullable { get; set; }

        public bool IsSelect { get; set; }

        public int Index { get; internal set; }

        public SearchPredicationEnum DefaultPredication { get; set; }

        public SearchOperationEnum DefaultOperation { get; set; }

        public string DefaultValue { get; set; }

        public SearchDateType DateType { get; set; }

        public virtual SearchOperationEnum Operation { get; set; }

        public virtual void Render(HtmlTextWriter writer, bool isLastItem)
        {
            writer.RenderBeginTag(HtmlTextWriterTag.Tr);

            #region 字段
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            this.RenderFields(writer);

            writer.RenderEndTag();
            #endregion

            #region 比较符
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            this.RenderOperations(writer);
            writer.RenderEndTag();
            #endregion

            #region 值域
            writer.RenderBeginTag(HtmlTextWriterTag.Td);

            this.isRenderValueFieldId = false;
            this.RenderContent(writer);
            if (!isRenderValueFieldId)
            {
                throw new NotImplementedException("必须在子类的RenderContent方法调用ReaderValueFieldId方法");
            }
            writer.RenderEndTag();
            #endregion

            #region 连接符
            if (this.Owner.SearchMode == SearchModeEnum.Complex)
            {
                writer.RenderBeginTag(HtmlTextWriterTag.Td);
                this.RenderConnections(writer, isLastItem);
                writer.RenderEndTag();
            }
            #endregion

            writer.RenderEndTag();
        }

        /*
        /// <summary>
        /// 输出值控件,
        /// </summary>
        /// <param name="writer"></param>
        protected virtual void RenderValueField(HtmlTextWriter writer)
        {
            bool isRenderContentMethodCall = false;
            StackTrace trace = new StackTrace();
            foreach (StackFrame frame in trace.GetFrames())
            {
                if (frame.GetMethod().Name == "RenderContent")
                {
                    isRenderContentMethodCall = true;
                    break;
                }
            }

            if (!isRenderContentMethodCall)
            {
                throw new NotSupportedException(" RenderValueField 方法必须在 RenderContent 方法内调用.");
            }

            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.Owner.ClientID + SearchItemBase.ValuesExtName);
            writer.AddAttribute(HtmlTextWriterAttribute.Name, this.Owner.ClientID + SearchItemBase.ValuesExtName);

            if (this.TagKey == HtmlFormTagEnum.Input)
            {
                if (this.DefaultValue != null)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Value, this.DefaultValue);
                }

                writer.RenderBeginTag(HtmlTextWriterTag.Input);
                writer.RenderEndTag();
            }
            else if (this.TagKey == HtmlFormTagEnum.Select)
            {
                if (this.DefaultValue != null)
                {
                    writer.AddAttribute(HtmlTextWriterAttribute.Value, this.DefaultValue);
                }

                writer.RenderBeginTag(HtmlTextWriterTag.Select);
                this.RenderValueFieldInnerContent(writer);
                writer.RenderEndTag();
            }
            else
            {
                writer.RenderBeginTag(HtmlTextWriterTag.Textarea);

                if (this.DefaultValue != null)
                {
                    writer.WriteEncodedText(this.DefaultValue);
                }

                writer.RenderEndTag();
            }

            this.isRenderValueField = true;
        }
         * */

        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        protected void ReaderValueFieldId(HtmlTextWriter writer)
        {
            isRenderValueFieldId = true;
            writer.AddAttribute(HtmlTextWriterAttribute.Id, this.Owner.ClientID + SearchItemBase.ValuesExtName);
            writer.AddAttribute(HtmlTextWriterAttribute.Name, this.Owner.ClientID + SearchItemBase.ValuesExtName);
        }

        protected virtual void RenderFields(HtmlTextWriter writer)
        {
            System.Web.UI.HtmlControls.HtmlSelect select = new HtmlSelect();
            select.Attributes.Add("onchange", "SearchChangeField(\"" + this.Owner.ClientID + "\", this, true);");
            select.ID = this.Owner.ClientID + SearchItemBase.FieldsSelectExtName;

            foreach (var item in this.Owner.Items)
            {
                select.Items.Add(new ListItem()
                {
                    Value = item.FieldName,
                    Text = item.Text,
                    Selected = (this.FieldName == item.FieldName && this.Text == item.Text)
                });
            }

            select.RenderControl(writer);

            System.Web.UI.HtmlControls.HtmlInputHidden hiden = new HtmlInputHidden();
            hiden.ID = this.Owner.ClientID + SearchItemBase.ItemInfosExtName;
            hiden.Value = this.ToString() + "|" + this.IsNullable.ToString() + "|" + this.DateType.ToString() + "|" + this.Index.ToString();

            System.Web.UI.HtmlControls.HtmlInputHidden hidenValuesplit = new HtmlInputHidden();
            hidenValuesplit.ID = this.Owner.ClientID + SearchItemBase.ValuesExtName;
            hidenValuesplit.Value = SearchView.ValueSplitStr;

            hiden.RenderControl(writer);
            hidenValuesplit.RenderControl(writer);
        }

        protected virtual void RenderOperations(HtmlTextWriter writer)
        {
            System.Web.UI.HtmlControls.HtmlSelect select = new HtmlSelect();
            select.ID = this.Owner.ClientID + SearchItemBase.OperationsSelectExtName;

            if ((this.Operation & SearchOperationEnum.Equal) == SearchOperationEnum.Equal)
            {
                select.Items.Add(new ListItem()
                {
                    Text = "等于",
                    Value = SearchOperationEnum.Equal.ToString(),
                    Selected = this.DefaultOperation == SearchOperationEnum.Equal
                });
            }

            if ((this.Operation & SearchOperationEnum.UnEqual) == SearchOperationEnum.UnEqual)
            {
                select.Items.Add(new ListItem()
                {
                    Text = "不等于",
                    Value = SearchOperationEnum.UnEqual.ToString(),
                    Selected = this.DefaultOperation == SearchOperationEnum.UnEqual
                });
            }

            if ((this.Operation & SearchOperationEnum.LessEqual) == SearchOperationEnum.LessEqual)
            {
                select.Items.Add(new ListItem()
                {
                    Text = "小于等于",
                    Value = SearchOperationEnum.LessEqual.ToString(),
                    Selected = this.DefaultOperation == SearchOperationEnum.LessEqual
                });
            }

            if ((this.Operation & SearchOperationEnum.MoreEqual) == SearchOperationEnum.MoreEqual)
            {
                select.Items.Add(new ListItem()
                {
                    Text = "大于等于",
                    Value = SearchOperationEnum.MoreEqual.ToString(),
                    Selected = this.DefaultOperation == SearchOperationEnum.MoreEqual
                });
            }

            if ((this.Operation & SearchOperationEnum.LessThan) == SearchOperationEnum.LessThan)
            {
                select.Items.Add(new ListItem()
                {
                    Text = "小于",
                    Value = SearchOperationEnum.LessThan.ToString(),
                    Selected = this.DefaultOperation == SearchOperationEnum.LessThan
                });
            }

            if ((this.Operation & SearchOperationEnum.MoreThan) == SearchOperationEnum.MoreThan)
            {
                select.Items.Add(new ListItem()
                {
                    Text = "大于",
                    Value = SearchOperationEnum.MoreThan.ToString(),
                    Selected = this.DefaultOperation == SearchOperationEnum.MoreThan
                });
            }

            if ((this.Operation & SearchOperationEnum.Include) == SearchOperationEnum.Include)
            {
                select.Items.Add(new ListItem()
                {
                    Text = "包含",
                    Value = SearchOperationEnum.Include.ToString(),
                    Selected = this.DefaultOperation == SearchOperationEnum.Include
                });
            }

            if ((this.Operation & SearchOperationEnum.UnInclude) == SearchOperationEnum.UnInclude)
            {
                select.Items.Add(new ListItem()
                {
                    Text = "不包含",
                    Value = SearchOperationEnum.UnInclude.ToString(),
                    Selected = this.DefaultOperation == SearchOperationEnum.UnInclude
                });
            }

            select.RenderControl(writer);
        }

        protected virtual void RenderConnections(HtmlTextWriter writer, bool isLastItem)
        {
            System.Web.UI.HtmlControls.HtmlSelect select = new HtmlSelect();
            select.ID = this.Owner.ClientID + SearchItemBase.ConnectionsSelectExtName;
            select.Attributes.Add("onchange", "SearchConnectionSelectChange('" + this.Owner.ClientID + "',this)");

            if (isLastItem)
            {

                select.Items.Add(new ListItem()
                {
                    Text = "+",
                    Value = "ADD",
                    Selected = true
                });

                select.Items.Add(new ListItem()
                {
                    Text = "并且",
                    Value = "AND"
                });

                select.Items.Add(new ListItem()
                {
                    Text = "或者",
                    Value = "OR"
                });
            }
            else
            {
                select.Items.Add(new ListItem()
              {
                  Text = "并且",
                  Value = "AND"
              });

                select.Items.Add(new ListItem()
                {
                    Text = "或者",
                    Value = "OR"
                });

                select.Items.Add(new ListItem()
                {
                    Text = "x",
                    Value = "DELETE"
                });

                select.SelectedIndex = (int)this.DefaultPredication;
            }

            select.RenderControl(writer);
        }

        /// <summary>
        /// 必须重写,并需要调用RenderValueField方法输出值控件
        /// </summary>
        /// <param name="writer"></param>
        protected abstract void RenderContent(HtmlTextWriter writer);

        public abstract object Clone();

        public SearchItemBase Clone(SearchItemBase clone)
        {
            clone.DateType = this.DateType;
            clone.DefaultOperation = this.DefaultOperation;
            clone.DefaultPredication = this.DefaultPredication;
            clone.ErrorMessage = this.ErrorMessage;
            clone.FieldName = this.FieldName;
            clone.IsNullable = this.IsNullable;
            clone.IsSelect = this.IsSelect;
            clone.IsValid = this.IsValid;
            clone.Operation = this.Operation;
            clone.Owner = this.Owner;
            clone.Text = this.Text;
            clone.Index = this.Index;
            clone.DefaultValue = this.DefaultValue;

            return clone;
        }

        #region IValidator 成员

        public string ErrorMessage { get; set; }

        public bool IsValid { get; set; }

        public void Validate()
        {

        }
        #endregion
    }
}
